package com.lizhenhua.fmmall.service.serviceImpl;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.lizhenhua.fmmall.entity.Users;

import com.lizhenhua.fmmall.mapper.UsersMapper;
import com.lizhenhua.fmmall.service.UserService;
import com.lizhenhua.fmmall.utils.Base64Utils;
import com.lizhenhua.fmmall.utils.MD5Utils;
import com.lizhenhua.fmmall.vo.ResStatus;
import com.lizhenhua.fmmall.vo.ResultVo;

import io.jsonwebtoken.JwtBuilder;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.apache.ibatis.annotations.Param;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import tk.mybatis.mapper.entity.Example;

import javax.annotation.Resource;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.concurrent.TimeUnit;

@Service
@Scope("singleton") //singleton 单线程设置
public class UserServiceImpl implements UserService {
    @Autowired
    UsersMapper userMapper;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    private ObjectMapper o = new ObjectMapper();
    @Override  // 登录操作
    public ResultVo checkLogin(String userName, String pwd) {
        //1. 根据账号查询信息
        Example example = new Example(Users.class);

        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("username", userName);
        List<Users> usersList = userMapper.selectByExample(example);
        // 判断是否查询到信息
        if (usersList.size() == 0) {
            return new ResultVo(ResStatus.NO, "登陆失败，用户名不存在", null);
        } else {
            Users users = usersList.get(0);
            // 对输入的密码进行加密
           String password = MD5Utils.md5(pwd);
            // 使用加密后的密码 和 user中的密码进行匹配
            if (users.getPassword().equals(password)) {
                // token方法
//                String token = Base64Utils.encode(userName+123456);
                // 使用jwt 生成token 工厂模式
                JwtBuilder builder = Jwts.builder();
                HashMap<String,Object> hashMap = new HashMap<>();
                hashMap.put("key1","value1");
                hashMap.put("key2","value2");
                String token = builder.setSubject(userName)
                        .setIssuedAt(new Date()) //创建token生成的时间
                        .setId(users.getUserId()+"") //  id 为Users的id
                        .setClaims(hashMap)  // map中可以存放用户的权限信息
                        .setExpiration(new Date(System.currentTimeMillis() + 24 * 60 * 60 * 1000))//设置过期时间
                        .signWith(SignatureAlgorithm.HS256, "aaa123")//设置加密方式 和加密密码
                        .compact();// .compact() 会返回一个字符串

                //当用户登录成功之后 以token为key 将信息保存到redis中
                try {
                    String userInfo = o.writeValueAsString(users);
                    System.out.println(userInfo);
                    stringRedisTemplate.boundValueOps(token).set(userInfo,20, TimeUnit.MINUTES);
                } catch (JsonProcessingException e) {
                    e.printStackTrace();
                }


                return new ResultVo(ResStatus.OK,token, users);
            } else {
                return new ResultVo(ResStatus.NO, "登陆失败,密码错误", null);
            }
        }


    }

    @Transactional // 定义成一个事务
    public ResultVo userResgit(String userName, String password) {

        //synchronized  线程锁  锁UserServiceImpl 这个类  必须是同一个线程才是同一个对象 这个锁才生效
        synchronized (this) {
            /**
             * 1. 根据用户查询，这个用户是否已经被注册
             */
            // 此处的Example应该是属于 tk.mybatis的
            Example example = new Example(Users.class);

            Example.Criteria criteria = example.createCriteria();
            criteria.andEqualTo("username", userName);

            List<Users> usersList = userMapper.selectByExample(example);
            Users users ;

            if (usersList.size() == 0) {
// MD5 工具类加密密码 返回类型为String类型
                MD5Utils.md5(password);
                users = new Users();
                users.setUsername(userName);
                users.setPassword(MD5Utils.md5(password));
                users.setUserImg("img/default.png");
                users.setUserRegtime(new Date());
                users.setUserModtime(new Date());
                int i = userMapper.insert(users);
                /**
                 * 2.如果没有进行注册 则进行保存操作
                 */

                if (i > 0) {
                    return new ResultVo(ResStatus.OK, "注册成功", users);
                } else {
                    return new ResultVo(ResStatus.NO, "注册失败", null);

                }

            } else {
                return new ResultVo(ResStatus.NO, "用户名已经被注册", null);
            }
        }
    }

    @Override
    public ResultVo usersList(Integer limit) {
        Example example = new Example(Users.class);

        Example.Criteria criteria = example.createCriteria();
        criteria.andLessThan("userId",limit);


        return new ResultVo(ResStatus.OK, "查询所有用户信息成功", userMapper.selectByExample(example));
    }
//            Users users = userMapper.checkName(userName);
//
//            if (users == null) {
//// MD5 工具类加密密码 返回类型为String类型
//                MD5Utils.md5(password);
//                users = new Users();
//                users.setUsername(userName);
//                users.setPassword(MD5Utils.md5(password));
//                users.setUserImg("img/default.png");
//                users.setUserRegtime(new Date());
//                users.setUserModtime(new Date());
//                int i = userMapper.insertUsers(users);
//                /**
//                 * 2.如果没有进行注册 则进行保存操作
//                 */
//
//                if (i > 0) {
//                    return new ResultVo(100, "注册成功", users);
//                } else {
//                    return new ResultVo(102, "注册失败", null);
//
//                }
//
//            } else {
//                return new ResultVo(101, "用户名已经被注册", null);
//            }
//
//        }
//    }






}
